import _ from 'lodash'
import Config from '../config.js'
import CryptoJS from 'crypto-js'
import JSEncrypt from 'jsencrypt'
// import Pinyin from 'pinyin';
import Services from './services'
import XmlParser from './xmlparser'
import Vue from 'vue'
const crypto = require('crypto')
import { Base64 } from 'js-base64'
import Proxy from './proxy'

/**
 * 工具类
 * @Author: wenjm
 * @Date: 2018-03-27 14:13:32
 * @Last Modified by: wenjm
 * @Last Modified time: 2022-11-01 23:23:32
 */
var util = _.extend({}, _, {
    get $f7() {
        return Vue.prototype.$f7
    },
    get $framework() {
        return Vue.prototype.$framework
    },
    // 获取图片的路径
    getImgSrc(attachmentId) {
        return `${Config.api.downThumb}?attachmentId=${attachmentId}`
    },
    // 获取外部图片的路径 (目前特种人员证书使用到)
    getOutsideImgSrc(attachmentId) {
        return `${Config.api.outsideDownThumb}?attachmentId=${attachmentId}`
    },
    // 获取文件路径
    getFileSrc(attachmentId) {
        return `${Config.api.download}?attachmentId=${attachmentId}`
    },
    appendUrl (url, map) {
        if (!url || !map) {
            return url;
        }
        Object.keys(map).forEach(function (key) {
            var join = url.indexOf("?") == -1 ? "?" : "&";
            url += join + key + "=" + encodeURI(map[key] || '');
        });
        return url;
    },
    // url 参数
    encodeSearchParams(obj) {
        const params = []
        Object.keys(obj).forEach((key) => {
            let value = obj[key]
            // 如果值为undefined置空
            if (typeof value === 'undefined') {
                value = ''
            }
            //使用encodeURIComponent进行编码
            if (Array.isArray(obj[key])) {
                //类型为数组的时候
                value.forEach((item) => {
                    params.push([key, encodeURIComponent(item)].join('='))
                })
            }
            if (
                Object.prototype.toString.call(obj[key]) === '[object Object]'
            ) {
                //类型为对象的时候
                Object.keys(obj[key]).forEach((item) => {
                    params.push(
                        [key, encodeURIComponent(obj[key][item])].join('=')
                    )
                })
            } else {
                params.push([key, encodeURIComponent(value)].join('='))
            }
        })
        return params.join('&')
    },
    //网络请求函数
    request(url, data, method) {
        return method === 'get'
            ? this.$f7.request.promise.getJSON(url, data)
            : this.$f7.request.promise.postJSON(url, data)
    },
    isDev() {
        if (process.env.NODE_ENV == 'development') {
            return true
        }
        return false
    },
    isProd() {
        if (process.env.NODE_ENV == 'development') {
            return false
        }
        return true
    },
    isUmSdk() {
        if (process.env.CONFIG_TYPE.includes('UM_PROD')) {
            return true
        } else {
            return false
        }
    },
    error(e) {
        if (this.isDev()) {
            console.error(e)
        }
    },
    isPromise(obj) {
        if (obj == undefined) {
            return false
        }
        return _.isObject(obj) && _.isFunction(obj.then)
    },
    random(lenght = 16) {
        var $chars =
            'ABCDEFGHIJKLMNOPQRSTWVUXYZabcdefghijklmnopqrstwvuxyz123456789'
        var maxPos = $chars.length
        var result = ''
        for (let i = 0; i < lenght; i++) {
            result += $chars.charAt(Math.floor(Math.random() * maxPos))
        }
        return result
    },
    buildArray(value) {
        if (value && _.isArray(value)) {
            return value.distinct()
        } else if (value) {
            return [value]
        } else {
            return []
        }
    },
    browser() {
        var Browser = {
            name: '',
            version: '',
        }
        var ua = navigator.userAgent.toLowerCase()
        var s
        ;(s = ua.match(/msie ([\d.]+)/))
            ? (Browser.ie = s[1])
            : (s = ua.match(/firefox\/([\d.]+)/))
            ? (Browser.firefox = s[1])
            : (s = ua.match(/chrome\/([\d.]+)/))
            ? (Browser.chrome = s[1])
            : (s = ua.match(/opera.([\d.]+)/))
            ? (Browser.opera = s[1])
            : (s = ua.match(/version\/([\d.]+).*safari/))
            ? (Browser.safari = s[1])
            : 0
        if (Browser.ie) {
            //Js判断为IE浏览器
            Browser.name = 'IE'
            Browser.version = Browser.ie
            return Browser
        }
        if (Browser.firefox) {
            //Js判断为火狐(firefox)浏览器
            Browser.name = 'Firefox'
            Browser.version = Browser.firefox
            return Browser
        }
        if (Browser.chrome) {
            //Js判断为谷歌chrome浏览器
            Browser.name = 'Chrome'
            Browser.version = Browser.chrome
            return Browser
        }
        if (Browser.opera) {
            //Js判断为opera浏览器
            Browser.name = 'Opera'
            Browser.version = Browser.opera
            return Browser
        }
        if (Browser.safari) {
            //Js判断为苹果safari浏览器
            Browser.name = 'Safari'
            Browser.version = Browser.safari
            return Browser
        }
        return Browser
    },
    pinyin(value, options) {
        options = options || {
            style: Pinyin.STYLE_NORMAL,
            heteronym: false,
        }
        return Pinyin(value, options)
    },
    pinyinString(value, options, spilt = '') {
        let r = util.pinyin(value, options)
        if (r) {
            return r.join(spilt)
        }
        return undefined
    },
    pinyinFirst(value) {
        let r = util.pinyin(value)
        if (r) {
            return r.join('').substring(0, 1)
        }
        return undefined
    },
    htmlEncode(html) {
        var temp = document.createElement('div')
        temp.textContent != undefined
            ? (temp.textContent = html)
            : (temp.innerText = html)
        var output = temp.innerHTML
        temp = null
        return output
    },
    htmlDecode(text) {
        var temp = document.createElement('div')
        temp.innerHTML = text
        var output = temp.innerText || temp.textContent
        temp = null
        return output
    },
    htmlClear(str, length) {
        str = str.replace(/<\/?[^>]*>/g, '')
        str = str.replace(/[ | ]*\n/g, '\n')
        str = str.replace(/\n[\s| | ]*\r/g, '\n')
        str = str.replace(/&nbsp;/gi, ' ')
        str = str.replace(/&emsp;/gi, ' ')
        str = str.replace(/&ldquo;/gi, '"')
        str = str.replace(/&rdquo;/gi, '"')
        return length && length > 0 && str.length > length
            ? str.substr(0, length) + '...'
            : str
    },
    getController(path = this.$f7.views.current.router.currentRoute.path) {
        let instance = Services.findInstance('controller', path)
        if (!instance && path.endsWith('/')) {
            instance = Services.findInstance(
                'controller',
                path.substring(0, path.length - 1)
            )
        }
        if (!instance && path.startsWith('/')) {
            instance = Services.findInstance('controller', path.substring(1))
        }
        return instance
    },
    getContext(path) {
        let con = this.getController(path)
        return con ? con.context : undefined
    },
    watchPosition(successCB, errorCB, option) {
        if (window.plus) {
            window.plus.geolocation.watchPosition(
                (pos) => {
                    successCB(pos)
                },
                function (e) {
                    if (_.isFunction(errorCB)) {
                        errorCB(e)
                    }
                    console.log(e)
                },
                option
            )
        } else {
            //Bmap
            window.setTimeout(() => {
                getCurrentPosition(successCB, errorCB, option)
            }, 5000)
        }
    },
    getCurrentPosition(successCB, errorCB, option) {
        // this.$f7.dialog.toast('正在定位中...');
        localStorage.setItem('CONFIG_TYPE',JSON.stringify(process.env.CONFIG_TYPE))
        if(process.env.CONFIG_TYPE.includes('UM_PROD')){
            console.log('umsdk-------',JSON.stringify(umSdk));
            localStorage.setItem('umsdk',JSON.stringify(umSdk))
            umSdk.getLocation({
                success: function (res) {
                    localStorage.setItem('umsdk成功回调',JSON.stringify(res))
                    successCB(res)
                },
                fail: function (err) {
                    errorCB(err)
                },
            })
            /*var geolocation = new BMap.Geolocation();
            geolocation.getCurrentPosition(function (pos) {
                let cpos = {
                    "coordsType": "bd09ll",
                    "address": {
                        "country": "中国",
                        "province": pos.address.province,
                        "city": pos.address.city,
                        "district": pos.address.district,
                        "street": pos.address.street,
                        "streetNum": pos.address.street_number,
                        "cityCode": pos.address.city_code
                    },
                    "addresses": "中国" + pos.address.province + pos.address.city + pos.address.street + pos.address.street_number,
                    "coords": {
                        "latitude": pos.latitude || pos.point.lat,
                        "longitude": pos.longitude || pos.point.lng,
                        "accuracy": pos.accuracy,
                        "altitude": pos.altitude,
                        "heading": pos.heading,
                        "speed": pos.speed || 0,
                        "altitudeAccuracy": 0
                    },
                    "timestamp": pos.timestamp || new Date().getTime()
                };
                if (this.getStatus() == BMAP_STATUS_SUCCESS) {
                    successCB(cpos);
                } else {
                    if (errorCB) {
                        errorCB(cpos);
                    } else {
                        self.$f7.dialog.toast("定位失败，请手动选择所在城市");
                    }
                }
            }, {
                enableHighAccuracy: true
            });*/
        }else if (window.plus) {
            
            // this.$f7.preloader.show()
            window.plus.geolocation.getCurrentPosition(
                (pos) => {
                    // this.$f7.preloader.hide()
                    localStorage.setItem('window.plus成功回调',JSON.stringify(pos))
                    successCB(pos)
                },
                (e) => {
                    // this.$f7.preloader.hide()
                    if (errorCB) {
                        errorCB(e)
                    } else {
                        this.$f7.dialog.toast('定位失败，请手动选择所在城市')
                    }
                },
                _.extend(
                    {
                        provider: 'system',
                        coordsType: 'wgs84',
                        // provider: 'baidu',
                        // coordsType: "bd09ll",
                        enableHighAccuracy: true,
                    },
                    option || {}
                )
            )
        }
    },
    encryptAES(data, deskey) {
        var key = CryptoJS.enc.Utf8.parse(deskey)
        var iv = CryptoJS.enc.Utf8.parse(deskey)
        var srcs = CryptoJS.enc.Utf8.parse(data)
        var encrypted = CryptoJS.AES.encrypt(srcs, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7,
        })
        srcs = CryptoJS.enc.Base64.stringify(encrypted.ciphertext)
        return srcs
    },
    decryptAES(data, deskey) {
        var key = CryptoJS.enc.Utf8.parse(deskey)
        var iv = CryptoJS.enc.Utf8.parse(deskey)
        var decrypted = CryptoJS.AES.decrypt(data, key, {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7,
        })
        return CryptoJS.enc.Utf8.stringify(decrypted)
    },
    encryptRSA(data, publicKey) {
        var encrypt = new JSEncrypt()
        encrypt.setPublicKey(publicKey)
        return encrypt.encrypt(data)
    },
    decryptRSA(data, privateKey) {
        var encrypt = new JSEncrypt()
        encrypt.setPrivateKey(privateKey)
        return encrypt.decrypt(data)
    },
    encryptLongRSA(data, publicKey) {
        var encrypt = new JSEncrypt()
        encrypt.setPublicKey(publicKey)
        return encrypt.encryptLong(data)
    },
    decryptLongRSA(data, privateKey) {
        var encrypt = new JSEncrypt()
        encrypt.setPrivateKey(privateKey)
        return encrypt.decryptLong(data)
    },
    md5Encrypt(data) {
        let hasher = crypto.createHash('md5')
        return hasher.update(data).digest('hex')
    },
    //十六进制转字节
    hexToBytes(hex) {
        for (var bytes = [], c = 0; c < hex.length; c += 2)
            bytes.push(parseInt(hex.substr(c, 2), 16))
        return bytes
    },
    // 字节转十六进制
    bytesToHex(bytes) {
        for (var hex = [], i = 0; i < bytes.length; i++) {
            hex.push((bytes[i] >>> 4).toString(16))
            hex.push((bytes[i] & 0xf).toString(16))
        }
        return hex.join('')
    },
    base64ToHex(e) {
        var b64map =
            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
        var b64pad = '='
        var c = ''
        var d
        var a = 0
        var b
        for (d = 0; d < e.length; ++d) {
            if (e.charAt(d) == b64pad) {
                break
            }
            var v = b64map.indexOf(e.charAt(d))
            if (v < 0) {
                continue
            }
            if (a == 0) {
                c += util.intToChar(v >> 2)
                b = v & 3
                a = 1
            } else {
                if (a == 1) {
                    c += util.intToChar((b << 2) | (v >> 4))
                    b = v & 15
                    a = 2
                } else {
                    if (a == 2) {
                        c += util.intToChar(b)
                        c += util.intToChar(v >> 2)
                        b = v & 3
                        a = 3
                    } else {
                        c += util.intToChar((b << 2) | (v >> 4))
                        c += util.intToChar(v & 15)
                        a = 0
                    }
                }
            }
        }
        if (a == 1) {
            c += util.intToChar(b << 2)
        }
        return c
    },
    hexTobase64(h) {
        var b64map =
            'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
        var b64pad = '='
        var i
        var c
        var ret = ''
        for (i = 0; i + 3 <= h.length; i += 3) {
            c = parseInt(h.substring(i, i + 3), 16)
            ret += b64map.charAt(c >> 6) + b64map.charAt(c & 63)
        }
        if (i + 1 == h.length) {
            c = parseInt(h.substring(i, i + 1), 16)
            ret += b64map.charAt(c << 2)
        } else if (i + 2 == h.length) {
            c = parseInt(h.substring(i, i + 2), 16)
            ret += b64map.charAt(c >> 2) + b64map.charAt((c & 3) << 4)
        }
        while ((ret.length & 3) > 0) ret += b64pad
        return ret
    },
    intToChar(a) {
        return '0123456789abcdefghijklmnopqrstuvwxyz'.charAt(a)
    },
    stringToByte(str) {
        var bytes = new Array()
        var len, c
        len = str.length
        for (var i = 0; i < len; i++) {
            c = str.charCodeAt(i)
            if (c >= 0x010000 && c <= 0x10ffff) {
                bytes.push(((c >> 18) & 0x07) | 0xf0)
                bytes.push(((c >> 12) & 0x3f) | 0x80)
                bytes.push(((c >> 6) & 0x3f) | 0x80)
                bytes.push((c & 0x3f) | 0x80)
            } else if (c >= 0x000800 && c <= 0x00ffff) {
                bytes.push(((c >> 12) & 0x0f) | 0xe0)
                bytes.push(((c >> 6) & 0x3f) | 0x80)
                bytes.push((c & 0x3f) | 0x80)
            } else if (c >= 0x000080 && c <= 0x0007ff) {
                bytes.push(((c >> 6) & 0x1f) | 0xc0)
                bytes.push((c & 0x3f) | 0x80)
            } else {
                bytes.push(c & 0xff)
            }
        }
        return bytes
    },
    byteToString(arr) {
        if (typeof arr === 'string') {
            return arr
        }
        var str = '',
            _arr = arr
        for (var i = 0; i < _arr.length; i++) {
            var one = _arr[i].toString(2),
                v = one.match(/^1+?(?=0)/)
            if (v && one.length == 8) {
                var bytesLength = v[0].length
                var store = _arr[i].toString(2).slice(7 - bytesLength)
                for (var st = 1; st < bytesLength; st++) {
                    store += _arr[st + i].toString(2).slice(2)
                }
                str += String.fromCharCode(parseInt(store, 2))
                i += bytesLength - 1
            } else {
                str += String.fromCharCode(_arr[i])
            }
        }
        return str
    },
    toJSON(value) {
        if (_.isObject(value)) {
            return value
        }
        if (_.isEmpty(value)) {
            return {}
        }
        return JSON.parse(value)
    },
    xmlToJSON(xml) {
        return new XmlParser().toJSON(xml)
    },
    xmlFromJSON(json) {
        return new XmlParser().toXML(json)
    },
    base64Encode(value) {
        return Base64.encode(value)
    },
    base64Decode(value) {
        return Base64.decode(value)
    },
    plusReady(callback) {
        if (window.plus) {
            callback()
        } else {
            document.addEventListener('plusready', callback)
        }
    },
    combineUrl(f, s) {
        if (f == undefined || s == undefined) {
            return f || s
        } else if (f.endsWith('/') && s.startsWith('/')) {
            return '{0}{1}'.format(f.substring(0, f.length - 1), s)
        } else if (f.endsWith('/') || s.startsWith('/')) {
            return '{0}{1}'.format(f, s)
        } else {
            return '{0}/{1}'.format(f, s)
        }
    },
    getLinePoint(point1, point2, offset) {
        let v =
            ((point1.y - point2.y) * (point2.x - point1.x - offset) * 1.0) /
            (point2.x - point1.x)
        return {
            x: point1.x + offset,
            y: point2.y + v,
        }
    },
    walkPoints(point1, point2, offset, timespan, callback) {
        if (point2.x - point1.x - offset > 0) {
            callback(point1)
            let v = this.getLinePoint(point1, point2, offset)
            if (v) {
                callback(v)
                this.walkPoints(v, point2, offset, timespan, callback)
            } else {
                callback(point2)
            }
        } else {
            callback(point1)
            window.setTimeout(() => {
                callback(point2)
            }, timespan)
        }
    },
    parse(expression, args) {
        function parseValue(exp, arg) {
            if (arg == undefined) {
                return ''
            } else if (exp.indexOf('.') > -1) {
                return parseValue(
                    exp.substring(exp.indexOf('.') + 1),
                    arg[exp.substring(0, exp.indexOf('.'))]
                )
            } else {
                let v = arg[exp]
                return v == undefined ? '' : v
            }
        }

        let rg = new RegExp('\\{(.*?)\\}', 'g')
        let result = expression
        let temp = rg.exec(expression)
        while (temp) {
            result = result.replace(
                new RegExp(temp[0], 'g'),
                parseValue(temp[1], args)
            )
            temp = rg.exec(expression)
        }
        return result
    },
    getDistance(lng1, lat1, lng2, lat2) {
        return Math.round(
            6378.138 *
                2 *
                Math.asin(
                    Math.sqrt(
                        Math.pow(
                            Math.sin(
                                ((lat2 * Math.PI) / 180 -
                                    (lat1 * Math.PI) / 180) /
                                    2
                            ),
                            2
                        ) +
                            Math.cos((lat2 * Math.PI) / 180) *
                                Math.cos((lat1 * Math.PI) / 180) *
                                Math.pow(
                                    Math.sin(
                                        ((lng2 * Math.PI) / 180 -
                                            (lng1 * Math.PI) / 180) /
                                            2
                                    ),
                                    2
                                )
                    )
                ) *
                1000
        )
    },
    mapProxy(url) {
        let req = {
            url: url,
        }
        Proxy.map(req)
        return req.url
    },
    mapProxyOnProd(url) {
        if (process.env.NODE_ENV == 'development') {
            return url
        } else {
            let req = {
                url: url,
            }
            Proxy.map(req)
            return req.url
        }
    },
    call(number) {
        if (window.plus) {
            plus.device.dial(number, true)
        }
    },
    send(mType, number = '') {
        let type = 1
        if (mType == 'mail') {
            type = plus.messaging.TYPE_EMAIL
        } else {
            type = plus.messaging.TYPE_SMS
        }
        let msg = plus.messaging.createMessage(type)
        msg.to = [number]
        plus.messaging.sendMessage(msg)
    },
    downloadFile(fileName, attachmentId, vm, url, filePath) {
        console.log(Config.setting.packageType)
        if (Config.setting.packageType == 'app') {
            if (!window.plus) {
                console.error('plus加载失败')
                return
            }
            let self = this
            let root =
                '_downloads/qmapp/' +
                filePath.substring(filePath.lastIndexOf('/') + 1)
            let extension = fileName.substring(fileName.lastIndexOf('.') + 1)
            plus.io.resolveLocalFileSystemURL(
                root,
                function (entry) {
                    vm.$f7.dialog.confirm(
                        '《' +
                            fileName +
                            '》' +
                            '已存在对应的缓存文件，是否需要重新下载更新',
                        () => {
                            entry.remove(
                                function () {
                                    console.log('删除成功')
                                    self.downloadMobileFile(
                                        url,
                                        vm,
                                        root,
                                        fileName,
                                        attachmentId,
                                        extension
                                    )
                                },
                                function () {
                                    console.error('留存文件删除失败,请稍后再试')
                                    self.downloadMobileFile(
                                        url,
                                        vm,
                                        root,
                                        fileName,
                                        attachmentId,
                                        extension
                                    )
                                }
                            )
                        },
                        () => {
                            self.downloadMobileFile(vm, entry.fullPath)
                        }
                    )
                },
                function (e) {
                    console.error(
                        '《' +
                            fileName +
                            '》暂未缓存1' +
                            '===' +
                            JSON.stringify(e)
                    )
                    self.downloadMobileFile(
                        url,
                        vm,
                        root,
                        fileName,
                        attachmentId,
                        extension
                    )
                }
            )
        } else {
            if (window.ipcRenderer && window.ipcRenderer.sendSync) {
                window.ipcRenderer.on('downstate', (event, arg) => {
                    console.log('下载状态：' + arg)
                })
                this.downloadPCFile(url)
            } else {
                this.downloadFileForPC(url)
            }
        }
    },
    downloadFileForPC(url, fileName) {
        if (!url) {
            console.error('downloadFileForPC url is invalid')
            return
        }
        window.open(url)
    },
    downloadPCFile(url) {
        window.ipcRenderer.send('download', url)
    },
    downloadMobileFile(url, vm, fileroot, fileName, attachmentId, fileType) {
        let self = this
        let progress = 10
        let dialog = null
        dialog = vm.$f7.dialog.progress('正在下载中···', progress)
        let dtask = window.plus.downloader.createDownload(
            url,
            {
                filename: fileroot,
            },
            function (downloder, status) {
                console.log('响应状态码====' + status)
                if (status == 200) {
                    plus.io.resolveLocalFileSystemURL(
                        downloder.filename,
                        function (entry) {
                            let filesize = downloder.downloadedSize / 1000000
                            filesize = filesize.toFixed(2)

                            let fullPath = entry.fullPath
                            console.log(fullPath)
                            vm.$f7.dialog.toast('《' + fileName + '》下载完成')

                            self.openFile(vm, fullPath)
                        },
                        function (e) {
                            vm.$f7.dialog.toast(
                                '《' + fileName + '》文件下载失败，请稍后重试！'
                            )
                            console.error('读取文件错误：' + e.message)
                        }
                    )
                } else {
                    vm.$f7.dialog.toast(
                        '《' + fileName + '》文件下载失败，请稍后重试！'
                    )
                    console.error('文件下载失败: ' + status)
                }
                dialog.close()
            }
        )

        dtask.addEventListener('statechanged', function (task, status) {
            if (!dtask) {
                return
            }
            switch (task.state) {
                case 1:
                    break
                case 2:
                    break
                case 3:
                    progress = Math.round(
                        (task.downloadedSize / task.totalSize) * 100
                    )
                    dialog.setProgress(progress)
                    dialog.setText(progress + '%')
                    if (progress === 100) {
                        progress = 0
                        dialog.close()
                    }
                    break
                case 4:
                    break
            }
        })
        dtask.start()
    },
    openFile(vm, fullPath) {
        let option = {}
        if (plus.os.name == 'iOS') {
            vm.$framework.viewer.openWeb(fullPath)
        } else if (plus.os.name == 'Android') {
            vm.$framework.viewer.openFile(fullPath)
        }
    },
    downloadPdf(fileName, attId, vm, url) {
        if (!window.plus) {
            console.error('plus加载失败,请Build后到hbuilderx运行到手机')
            return
        }
        url = Config.info.server + url
        let self = this
        let root = '_downloads/qmapp/' + fileName
        fileName = fileName.replace(/\n/g, '').replace(/\s/g, '')
        if (fileName.length > 85) {
            fileName =
                fileName.substring(0, 50) +
                fileName.substring(fileName.lastIndexOf('.'))
        }
        let extension = fileName.substring(fileName.lastIndexOf('.') + 1)
        vm.$framework.db.attachfile
            .get({
                attachId: attId,
            })
            .then((attach) => {
                if (attach && attach.relativePath) {
                    plus.io.resolveLocalFileSystemURL(
                        attach.relativePath,
                        function (entry) {
                            vm.$f7.dialog.confirm(
                                '《' +
                                    fileName +
                                    '》' +
                                    '已存在对应的缓存文件，是否需要重新下载',
                                () => {
                                    entry.remove(
                                        function () {
                                            vm.$framework.db.attachfile.delete(
                                                attach.id
                                            )
                                            console.log('删除成功')
                                            self.downloadPdfPlus(
                                                url,
                                                vm,
                                                root,
                                                fileName,
                                                attId,
                                                extension
                                            )
                                        },
                                        function () {
                                            console.error(
                                                '留存文件删除失败,请稍后再试'
                                            )
                                        }
                                    )
                                },
                                () => {
                                    self.openPdf(vm, attach.relativePath)
                                }
                            )
                        },
                        function (e) {
                            console.error(
                                '《' +
                                    fileName +
                                    '》暂未缓存1' +
                                    '===' +
                                    JSON.stringify(e)
                            )
                            self.downloadPdfPlus(
                                url,
                                vm,
                                root,
                                fileName,
                                attId,
                                extension
                            )
                        }
                    )
                } else {
                    self.downloadPdfPlus(
                        url,
                        vm,
                        root,
                        fileName,
                        attId,
                        extension
                    )
                }
            })
            .catch((e) => {
                self.downloadPdfPlus(url, vm, root, fileName, attId, extension)
                console.error(
                    '《' + fileName + '》暂未缓存2' + '===' + JSON.stringify(e)
                )
            })
    },
    async downloadPdfPlus(url, vm, root, fileName, attachmentId, extension) {
        let self = this
        let user = await vm.$framework.account.getUser()
        let dtask = window.plus.downloader.createDownload(
            url,
            {
                filename: root,
            },
            function (downloder, status) {
                if (status == 200) {
                    plus.io.resolveLocalFileSystemURL(
                        downloder.filename,
                        function (entry) {
                            let filesize = downloder.downloadedSize / 1000000
                            filesize = filesize.toFixed(2)
                            let fullPath = entry.fullPath
                            let relativePath = decodeURI(downloder.filename)
                            console.log('fullPath:' + fullPath)
                            console.log('relativePath:' + relativePath)
                            let beforeOneMonth = new Date()
                            beforeOneMonth.setMonth(
                                beforeOneMonth.getMonth() - 2
                            )
                            vm.$framework.db.attachfile.add({
                                name: fileName,
                                path: fullPath,
                                relativePath: relativePath,
                                size: filesize,
                                type: extension,
                                date: new Date(),
                                user: user.userName,
                                attachId: attachmentId,
                            })
                            self.openPdf(vm, relativePath)
                        },
                        function (e) {
                            vm.$f7.dialog.toast(
                                '《' + fileName + '》下载失败，请稍后重试！'
                            )
                            console.error('读取文件错误：' + e.message)
                        }
                    )
                } else {
                    vm.$f7.dialog.toast(
                        '《' + fileName + '》下载失败，请稍后重试！'
                    )
                    console.error('文件下载失败: ' + status)
                }
            }
        )
        dtask.start()
    },
    openPdf(vm, fullPath) {
        if (vm.$f7.device.ios) {
            // 坑1：ios的，请确保filename不是乱码的(有可能下载下来的就是乱码的)，不然找不到文件
            vm.$f7.views.current.router.navigate(
                '/viewer/fileView?path=' +
                    decodeURI(
                        window.plus.io.convertLocalFileSystemURL(fullPath)
                    )
            )
        } else {
            vm.$f7.views.current.router.navigate(
                '/viewer/fileView?path=' +
                    window.plus.io.convertLocalFileSystemURL(fullPath)
            )
        }
    },
    /** 解除APP锁定屏幕方向 */
    unlockOrientation() {
        if (!window.plus) {
            return
        }

        plus.screen.unlockOrientation()
    },

    /** APP锁定屏幕方向
     * @param {String} orientation 锁定屏幕方向的类型：portrait-primary/top:竖屏(默认)；portrait-secondary/buttom:竖屏反向；landscape-primary/right:屏幕正方向按顺时针旋转90度；landscape-secondary/left:屏幕正方向按顺时针旋转270度；
     */
    lockOrientation(orientation) {
        if (!window.plus) {
            return
        }
        if (orientation) {
            switch (orientation) {
                case 'top':
                    orientation = 'portrait-primary'
                    break
                case 'buttom':
                    orientation = 'portrait-secondary'
                    break
                case 'right':
                    orientation = 'landscape-primary'
                    break
                case 'left':
                    orientation = 'landscape-secondary'
                    break
            }
        } else {
            orientation = 'portrait-primary'
        }
        plus.screen.lockOrientation(orientation)
    },
    /** 是否苹果端 */
    isApple() {
        return window.plus.os.vendor == 'Apple' || window.plus.os.name == 'iOS'
    },
    /** 是否为平板；平板返回true */
    isPad() {
        if (!window.plus) {
            return window.screen.width > window.screen.height // 宽屏
        }

        var screen = plus.screen
        var x = screen.dpiX > 0 ? Math.pow(screen.width / screen.dpiX, 2) : 0
        var y = screen.dpiY > 0 ? Math.pow(screen.height / screen.dpiY, 2) : 0
        if (Math.sqrt(x + y) >= 7.0) {
            return true
        }

        return false
    },
    // 是否从质量检测首页跳转
    backQualityList(url) {
        if (window.localStorage.getItem('isqualityList')) {
            this.$f7.views.current.router.navigate(url)
        } else {
            if (window.qmsdk && window.plus) {
                window.qmsdk.close()
            }
        }
    },
    getPromise(url, params) {
        var self = this
        return new Promise((rs, rj) => {
            self.$f7.request.post(
                url,
                params,
                (rlt) => {
                    if (typeof rlt == 'string') {
                        rlt = JSON.parse(rlt)
                    }
                    rs(rlt)
                },
                (rlt) => {
                    rlt.message = '获取数据失败，请稍后重试'
                    rj(rlt)
                }
            )
        })
    },
})

/**
 * 即将删除的方法，请勿使用
 * @deprecated
 */
util.mapApi = function (url, isPrefix = true) {
    if (process.env.NODE_ENV == 'development') {
        return connect(isPrefix === true ? Config.api.prefix : undefined, url)
    }
    var mapUrl = url
    if (
        mapUrl != undefined &&
        !mapUrl.startsWith('http') &&
        Config.api.server
    ) {
        mapUrl = connect(
            Config.api.server,
            isPrefix === true ? Config.api.prefix : undefined
        )
        mapUrl = connect(mapUrl, url)
    }

    function connect(f, s) {
        if (s == undefined) {
            return f
        } else if (f == undefined) {
            return s
        } else if (f.endsWith('/') && s.startsWith('/')) {
            return '{0}{1}'.format(f.substring(0, f.length - 1), s)
        } else if (f.endsWith('/') || s.startsWith('/')) {
            return '{0}{1}'.format(f, s)
        } else {
            return '{0}/{1}'.format(f, s)
        }
    }

    return mapUrl
}

/**
 * 即将删除的方法，请勿使用
 * @deprecated
 */
util.limitAccess = function (
    key,
    times,
    count,
    successCallback,
    limitCallback
) {
    var m = fw.storage.getItem(key)
    if (m) {
        var sec = parseInt((new Date() - new Date(m.date)) / 1000)
        var timeVal = parseInt(times.substring(0, times.length - 1))
        if (times.endsWith('s') && sec > timeVal) {
            m = null
        } else if (times.endsWith('m') && parseInt(sec / 60) > timeVal) {
            m = null
        } else if (times.endsWith('h') && parseInt(sec / 60 / 60) > timeVal) {
            m = null
        } else if (
            times.endsWith('d') &&
            parseInt(sec / 60 / 60 / 24) > timeVal
        ) {
            m = null
        }
    }
    if (m && m.count > count) {
        if (limitCallback) {
            if (typeof limitCallback == 'function') {
                limitCallback()
            } else {
                app.dialog.alert(_.toString(limitCallback))
            }
        }
    } else {
        successCallback()
        update()
    }

    function update() {
        if (m) {
            m = _.extend(m, {
                count: m.count + 1,
            })
        } else {
            m = {
                date: new Date(),
                count: 1,
            }
        }
        fw.storage.setItem(key, m)
    }
}

export default util
